home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Menus.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  28KB  |  1,184 lines

  1. /*
  2. **    Menus.c
  3. **
  4. **    Routines that deal with pull-down-menu management
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* PrepareLocalizedMenu(struct NewMenu **NewMenuPtr,WORD *NumMenuEntryPtr):
  17.      *
  18.      *    Set up the main menu.
  19.      */
  20.  
  21. VOID
  22. PrepareLocalizedMenu(struct NewMenu **NewMenuPtr,WORD *NumMenuEntryPtr)
  23. {
  24.     struct LocaleNewMenu
  25.     {
  26.         UBYTE    lnm_Type;            /* Menu template type. */
  27.         LONG    lnm_LabelID;        /* Menu's label */
  28.         STRPTR    lnm_CommKey;        /* MenuItem Command Key Equiv */
  29.         UWORD    lnm_Flags;            /* Menu or MenuItem flags (see note) */
  30.         LONG    lnm_MutualExclude;    /* MenuItem MutualExclude word */
  31.         ULONG    lnm_UserData;        /* For your own use, see note */
  32.     };
  33.  
  34.     #define LNM_BARLABEL -1
  35.  
  36.     STATIC struct LocaleNewMenu LocalNewMenu[] =
  37.     {
  38.         { NM_TITLE, MSG_TERMDATA_PROJECT_MEN },
  39.         {  NM_ITEM, MSG_TERMDATA_SAVE_SCREEN_AS_MEN },
  40.         {   NM_SUB, MSG_TERMDATA_SAVE_AS_PICTURE_MEN,        NULL,    NULL,    NULL,    MEN_SAVE_AS_PICTURE },
  41.         {   NM_SUB, MSG_TERMDATA_SAVE_AS_TEXT_MEN,            NULL,    NULL,    NULL,    MEN_SAVE_AS_TEXT },
  42.         {  NM_ITEM, LNM_BARLABEL },
  43.         {  NM_ITEM, MSG_TERMDATA_PRINT_MEN },
  44.         {   NM_SUB, MSG_TERMDATA_PRINT_SCREEN_MEN,            NULL,    NULL,    NULL,    MEN_PRINT_SCREEN },
  45.         {   NM_SUB, MSG_TERMDATA_PRINT_SCREEN_GFX_MEN,        NULL,    NULL,    NULL,    MEN_PRINT_SCREEN_AS_GFX },
  46.         {   NM_SUB, MSG_TERMDATA_PRINT_CLIP_MEN,            NULL,    NULL,    NULL,    MEN_PRINT_CLIP },
  47.         {  NM_ITEM, LNM_BARLABEL },
  48.         {  NM_ITEM, MSG_TERMDATA_CAPTURE_MEN },
  49.         {   NM_SUB, MSG_TERMDATA_CAPTURE_TO_FILE_MEN,        NULL,    TICK,    NULL,    MEN_CAPTURE_TO_FILE },
  50.         {   NM_SUB, MSG_TERMDATA_CAPTURE_TO_RAW_FILE_MEN,    NULL,    TICK,    NULL,    MEN_CAPTURE_TO_RAW_FILE },
  51.         {   NM_SUB, MSG_TERMDATA_CAPTURE_TO_PRINTER_MEN,    NULL,    TICK,    NULL,    MEN_CAPTURE_TO_PRINTER },
  52.         {  NM_ITEM, LNM_BARLABEL },
  53.         {  NM_ITEM, MSG_TERMDATA_ICONIFY_MEN,                NULL,    NULL,    NULL,    MEN_ICONIFY },
  54.         {  NM_ITEM, LNM_BARLABEL },
  55.         {  NM_ITEM, MSG_TERMDATA_ABOUT_MEN,                    NULL,    NULL,    NULL,    MEN_ABOUT },
  56.         {  NM_ITEM, LNM_BARLABEL },
  57.         {  NM_ITEM, MSG_TERMDATA_QUIT_MEN,                    NULL,    NULL,    NULL,    MEN_QUIT },
  58.  
  59.         { NM_TITLE, MSG_TERMDATA_EDIT_MEN },
  60.         {  NM_ITEM, MSG_TERMDATA_COPY_MEN,                    NULL,    NULL,    NULL,    MEN_COPY },
  61.         {  NM_ITEM, MSG_TERMDATA_PASTE_MEN,                    NULL,    NULL,    NULL,    MEN_PASTE },
  62.         {  NM_ITEM, MSG_TERMDATA_CLEAR_MEN,                    NULL,    NULL,    NULL,    MEN_CLEAR },
  63.         {  NM_ITEM, LNM_BARLABEL },
  64.         {  NM_ITEM, MSG_SELECT_ALL_MEN,                        NULL,    NULL,    NULL,    MEN_SELECT_ALL },
  65.  
  66.         { NM_TITLE, MSG_TERMDATA_COMMANDS_MEN },
  67.         {  NM_ITEM, MSG_TERMDATA_EXECUTE_DOS_COMMAND_MEN,    NULL,    NULL,    NULL,    MEN_EXECUTE_DOS_COMMAND },
  68.         {  NM_ITEM, MSG_TERMDATA_EXECUTE_REXX_COMMAND_MEN,    NULL,    NULL,    NULL,    MEN_EXECUTE_REXX_COMMAND },
  69.         {  NM_ITEM, LNM_BARLABEL },
  70.         {  NM_ITEM, MSG_TERMDATA_RECORD_MEN,                NULL,    TICK,    NULL,    MEN_RECORD },
  71.         {  NM_ITEM, MSG_TERMDATA_RECORD_LINE_MEN,            NULL,    TICK,    NULL,    MEN_RECORD_LINE },
  72.         {  NM_ITEM, LNM_BARLABEL },
  73.         {  NM_ITEM, MSG_TERMDATA_EDIT_TRAPS_MEN,            NULL,    NULL,    NULL,    MEN_EDIT_TRAPS },
  74.         {  NM_ITEM, MSG_TERMDATA_DISABLE_TRAPS_MEN,            NULL,    TICK,    NULL,    MEN_DISABLE_TRAPS },
  75.  
  76.         { NM_TITLE, MSG_TERMDATA_PHONE_MEN },
  77.         {  NM_ITEM, MSG_TERMDATA_PHONEBOOK_MEN,                NULL,    NULL,    NULL,    MEN_PHONEBOOK },
  78.         {  NM_ITEM, MSG_TERMDATA_REDIAL_MEN,                NULL,    NULL,    NULL,    MEN_REDIAL },
  79.         {  NM_ITEM, MSG_TERMDATA_DIAL_NUMBER_MEN,            NULL,    NULL,    NULL,    MEN_DIAL_NUMBER },
  80.         {  NM_ITEM, LNM_BARLABEL },
  81.         {  NM_ITEM, MSG_TERMDATA_SEND_BREAK_MEN,            NULL,    NULL,    NULL,    MEN_SEND_BREAK },
  82.         {  NM_ITEM, MSG_TERMDATA_HANG_UP_MEN,                NULL,    NULL,    NULL,    MEN_HANG_UP },
  83.         {  NM_ITEM, LNM_BARLABEL },
  84.         {  NM_ITEM, MSG_TERMDATA_WAIT_MEN,                    NULL,    NULL,    NULL,    MEN_WAIT },
  85.         {  NM_ITEM, LNM_BARLABEL },
  86.         {  NM_ITEM, MSG_TERMDATA_FLUSH_BUFFER_MEN,            NULL,    NULL,    NULL,    MEN_FLUSH_BUFFER },
  87.         {  NM_ITEM, MSG_TERMDATA_RELEASE_DEVICE_MEN,        NULL,    NULL,    NULL,    MEN_RELEASE_DEVICE },
  88.  
  89.         { NM_TITLE, MSG_TERMDATA_XFER_MEN },
  90.         {  NM_ITEM, MSG_TERMDATA_UPLOAD_ASCII_MEN,            NULL,    NULL,    NULL,    MEN_UPLOAD_ASCII },
  91.         {  NM_ITEM, MSG_TERMDATA_DOWNLOAD_ASCII_MEN,        NULL,    NULL,    NULL,    MEN_DOWNLOAD_ASCII },
  92.         {  NM_ITEM, LNM_BARLABEL },
  93.         {  NM_ITEM, MSG_TERMDATA_UPLOAD_TEXT_MEN,            NULL,    NULL,    NULL,    MEN_UPLOAD_TEXT },
  94.         {  NM_ITEM, MSG_TERMDATA_DOWNLOAD_TEXT_MEN,            NULL,    NULL,    NULL,    MEN_DOWNLOAD_TEXT },
  95.         {  NM_ITEM, MSG_TERMDATA_EDIT_AND_UPLOAD_TEXT_MEN,    NULL,    NULL,    NULL,    MEN_EDIT_AND_UPLOAD_TEXT },
  96.         {  NM_ITEM, LNM_BARLABEL },
  97.         {  NM_ITEM, MSG_TERMDATA_UPLOAD_BINARY_MEN,            NULL,    NULL,    NULL,    MEN_UPLOAD_BINARY },
  98.         {  NM_ITEM, MSG_TERMDATA_DOWNLOAD_BINARY_MEN,        NULL,    NULL,    NULL,    MEN_DOWNLOAD_BINARY },
  99.  
  100.         { NM_TITLE, MSG_TERMDATA_BUFFER_MEN },
  101.         {  NM_ITEM, MSG_TERMDATA_CLEAR_BUFFER_MEN,            NULL,    NULL,    NULL,    MEN_CLEAR_BUFFER },
  102.         {  NM_ITEM, MSG_TERMDATA_DISPLAY_BUFFER_MEN,        NULL,    NULL,    NULL,    MEN_DISPLAY_BUFFER },
  103.         {  NM_ITEM, MSG_TERMDATA_CLOSE_BUFFER_MEN,            NULL,    NULL,    NULL,    MEN_CLOSE_BUFFER },
  104.         {  NM_ITEM, LNM_BARLABEL },
  105.         {  NM_ITEM, MSG_TERMDATA_FREEZE_BUFFER_MEN,            NULL,    TICK,    NULL,    MEN_FREEZE_BUFFER },
  106.         {  NM_ITEM, LNM_BARLABEL },
  107.         {  NM_ITEM, MSG_TERMDATA_OPEN_BUFFER_MEN,            NULL,    NULL,    NULL,    MEN_OPEN_BUFFER },
  108.         {  NM_ITEM, MSG_TERMDATA_SAVE_BUFFER_AS_MEN,        NULL,    NULL,    NULL,    MEN_SAVE_BUFFER_AS },
  109.  
  110.         { NM_TITLE, MSG_TERMDATA_SCREEN_MEN },
  111.         {  NM_ITEM, MSG_TERMDATA_CLEAR_SCREEN_MEN,            NULL,    NULL,    NULL,    MEN_CLEAR_SCREEN },
  112.         {  NM_ITEM, MSG_TERMDATA_RESET_FONT_MEN,            NULL,    NULL,    NULL,    MEN_RESET_FONT },
  113.         {  NM_ITEM, MSG_TERMDATA_RESET_STYLES_MEN,            NULL,    NULL,    NULL,    MEN_RESET_STYLES },
  114.         {  NM_ITEM, MSG_TERMDATA_RESET_TERMINAL_MEN,        NULL,    NULL,    NULL,    MEN_RESET_TERMINAL },
  115.  
  116.         { NM_TITLE, MSG_TERMDATA_SETTINGS_MEN },
  117.         {  NM_ITEM, MSG_TERMDATA_SERIAL_MEN,                NULL,    NULL,    NULL,    MEN_SERIAL },
  118.         {  NM_ITEM, MSG_TERMDATA_MODEM_MEN,                    NULL,    NULL,    NULL,    MEN_MODEM },
  119.         {  NM_ITEM, MSG_TERMDATA_SCREEN_PREFS_MEN,            NULL,    NULL,    NULL,    MEN_SCREEN },
  120.         {  NM_ITEM, MSG_TERMDATA_TERMINAL_MEN,                NULL,    NULL,    NULL,    MEN_TERMINAL },
  121.         {  NM_ITEM, MSG_TERMDATA_SET_EMULATION_MEN,            NULL,    NULL,    NULL,    MEN_SET_EMULATION },
  122.         {  NM_ITEM, MSG_TERMDATA_CLIPBOARD_PREFS_MEN,        NULL,    NULL,    NULL,    MEN_CLIPBOARD },
  123.         {  NM_ITEM, MSG_TERMDATA_CAPTURE_PREFS_MEN,            NULL,    NULL,    NULL,    MEN_CAPTURE },
  124.         {  NM_ITEM, MSG_TERMDATA_COMMANDS_PREFS_MEN,        NULL,    NULL,    NULL,    MEN_COMMANDS },
  125.         {  NM_ITEM, MSG_TERMDATA_MISC_MEN,                    NULL,    NULL,    NULL,    MEN_MISC },
  126.         {  NM_ITEM, MSG_TERMDATA_PATH_MEN,                    NULL,    NULL,    NULL,    MEN_PATH },
  127.         {  NM_ITEM, MSG_TERMDATA_TRANSFER_PROTOCOL_MEN,        NULL,    NULL,    NULL,    MEN_TRANSFER_PROTOCOL },
  128.         {  NM_ITEM, LNM_BARLABEL },
  129.         {  NM_ITEM, MSG_TERMDATA_TRANSFER_MEN,                NULL,    NULL,    NULL,    MEN_TRANSFER },
  130.         {  NM_ITEM, MSG_TERMDATA_TRANSLATION_MEN,            NULL,    NULL,    NULL,    MEN_TRANSLATION },
  131.         {  NM_ITEM, MSG_TERMDATA_MACROS_MEN,                NULL,    NULL,    NULL,    MEN_MACROS },
  132.         {  NM_ITEM, MSG_TERMDATA_CURSORKEYS_MEN,            NULL,    NULL,    NULL,    MEN_CURSORKEYS },
  133.         {  NM_ITEM, MSG_TERMDATA_FAST_MACROS_MEN,            NULL,    NULL,    NULL,    MEN_FAST_MACROS },
  134.         {  NM_ITEM, MSG_TERMDATA_HOTKEYS_MEN,                NULL,    NULL,    NULL,    MEN_HOTKEYS },
  135.         {  NM_ITEM, MSG_TERMDATA_SPEECH_MEN,                NULL,    NULL,    NULL,    MEN_SPEECH },
  136.         {  NM_ITEM, MSG_TERMDATA_SOUND_MEN,                    NULL,    NULL,    NULL,    MEN_SOUND },
  137.         {  NM_ITEM, MSG_AREACODES_MEN,                        NULL,    NULL,    NULL,    MEN_RATES },
  138.         {  NM_ITEM, LNM_BARLABEL },
  139.         {  NM_ITEM, MSG_TERMDATA_OPEN_SETTINGS_MEN,            NULL,    NULL,    NULL,    MEN_OPEN_SETTINGS },
  140.         {  NM_ITEM, MSG_TERMDATA_SAVE_SETTINGS_MEN,            NULL,    NULL,    NULL,    MEN_SAVE_SETTINGS },
  141.         {  NM_ITEM, MSG_TERMDATA_SAVE_SETTINGS_AS_MEN,        NULL,    NULL,    NULL,    MEN_SAVE_SETTINGS_AS },
  142.  
  143.         { NM_TITLE, MSG_TERMDATA_WINDOWS_MEN },
  144.         {  NM_ITEM, MSG_TERMDATA_STATUS_WINDOW_MEN,            NULL,    TICK,    NULL,    MEN_STATUS_WINDOW },
  145.         {  NM_ITEM, MSG_TERMDATA_REVIEW_WINDOW_MEN,            NULL,    TICK,    NULL,    MEN_REVIEW_WINDOW },
  146.         {  NM_ITEM, MSG_TERMDATA_PACKET_WINDOW_MEN,            NULL,    CHECKIT,NULL,    MEN_PACKET_WINDOW },
  147.         {  NM_ITEM, MSG_TERMDATA_CHAT_LINE_MEN,                NULL,    TICK,    NULL,    MEN_CHAT_LINE },
  148.         {  NM_ITEM, MSG_TERMDATA_FAST_MACROS_WINDOW_MEN,    NULL,    TICK,    NULL,    MEN_FAST_MACROS_WINDOW },
  149.         {  NM_ITEM, MSG_TERMDATA_MATRIX_WINDOW_MEN,            NULL,    TICK,    NULL,    MEN_MATRIX_WINDOW },
  150.         {  NM_ITEM, MSG_TERMDATA_UPLOAD_QUEUE_WINDOW_MEN,    NULL,    NULL,    NULL,    MEN_UPLOAD_QUEUE_WINDOW },
  151.  
  152.         { NM_TITLE, MSG_TERMDATA_DIALING_MEN,                NULL,    NULL,    NULL,    MEN_EXTRA_DIAL },
  153.         {   NM_END }
  154.     };
  155.  
  156.     STRPTR String;
  157.     LONG i;
  158.  
  159.     for(i = 0 ; LocalNewMenu[i].lnm_Type != NM_END ; i++)
  160.     {
  161.         if(LocalNewMenu[i].lnm_LabelID != LNM_BARLABEL)
  162.         {
  163.             String = LocaleString(LocalNewMenu[i].lnm_LabelID);
  164.  
  165.             if(String[1] == 0)
  166.             {
  167.                 LocalNewMenu[i].lnm_CommKey = String;
  168.  
  169.                 String += 2;
  170.             }
  171.  
  172.             LocalNewMenu[i].lnm_LabelID = (LONG)String;
  173.         }
  174.     }
  175.  
  176.     *NewMenuPtr            = (struct NewMenu *)&LocalNewMenu[0];
  177.     *NumMenuEntryPtr    = i + 1;
  178. }
  179.  
  180.     /* CopyItemFlags(struct MenuItem *Src,struct MenuItem *Dst):
  181.      *
  182.      *    Copy single menu item flags from one menu strip
  183.      *    to another.
  184.      */
  185.  
  186. STATIC VOID
  187. CopyItemFlags(struct MenuItem *Src,struct MenuItem *Dst)
  188. {
  189.     while(Src && Dst)
  190.     {
  191.         if(Src->SubItem)
  192.             CopyItemFlags(Src->SubItem,Dst->SubItem);
  193.  
  194.         Dst->Flags = Src->Flags;
  195.  
  196.         Src = Src->NextItem;
  197.         Dst = Dst->NextItem;
  198.     }
  199. }
  200.  
  201.     /* CopyMenuFlags(struct Menu *Src,struct Menu *Dst):
  202.      *
  203.      *    Copy menu flags from one menu strip to
  204.      *    another.
  205.      */
  206.  
  207. STATIC VOID
  208. CopyMenuFlags(struct Menu *Src,struct Menu *Dst)
  209. {
  210.     struct MenuItem *SrcItem,*DstItem;
  211.  
  212.     while(Src && Dst)
  213.     {
  214.             /* Don't touch the quick dial menu. If CopyMenuFlags() */
  215.             /* is called its contents are likely to have changed */
  216.  
  217.         if((ULONG)GTMENU_USERDATA(Src) == DIAL_MENU_LIMIT)
  218.             break;
  219.         else
  220.         {
  221.             SrcItem = Src->FirstItem;
  222.             DstItem = Dst->FirstItem;
  223.  
  224.             while(SrcItem && DstItem)
  225.             {
  226.                 CopyItemFlags(SrcItem,DstItem);
  227.  
  228.                 SrcItem = SrcItem->NextItem;
  229.                 DstItem = DstItem->NextItem;
  230.             }
  231.  
  232.             Src = Src->NextMenu;
  233.             Dst = Dst->NextMenu;
  234.         }
  235.     }
  236. }
  237.  
  238.     /* SetMenuStrips(struct Menu *Menu):
  239.      *
  240.      *    Set a menu for all windows that support it.
  241.      */
  242.  
  243. VOID
  244. SetMenuStrips(struct Menu *Menu)
  245. {
  246.     ObtainSemaphore(&MenuSemaphore);
  247.  
  248.     if(Window)
  249.         SetMenuStrip(Window,Menu);
  250.  
  251.     if(StatusWindow)
  252.         SetMenuStrip(StatusWindow,Menu);
  253.  
  254.     if(FastWindow)
  255.         SetMenuStrip(FastWindow,Menu);
  256.  
  257.     ReleaseSemaphore(&MenuSemaphore);
  258. }
  259.  
  260.     /* ResetMenuStrips(struct Menu *Menu):
  261.      *
  262.      *    Reset a menu for all windows that support it.
  263.      */
  264.  
  265. VOID
  266. ResetMenuStrips(struct Menu *Menu)
  267. {
  268.     ObtainSemaphore(&MenuSemaphore);
  269.  
  270.     if(Window)
  271.         ResetMenuStrip(Window,Menu);
  272.  
  273.     if(StatusWindow)
  274.         ResetMenuStrip(StatusWindow,Menu);
  275.  
  276.     if(FastWindow)
  277.         ResetMenuStrip(FastWindow,Menu);
  278.  
  279.     ReleaseSemaphore(&MenuSemaphore);
  280. }
  281.  
  282.     /* ClearMenuStrips():
  283.      *
  284.      *    Clear a menu of all windows that support it.
  285.      */
  286.  
  287. VOID
  288. ClearMenuStrips()
  289. {
  290.     ObtainSemaphore(&MenuSemaphore);
  291.  
  292.     if(Window)
  293.         ClearMenuStrip(Window);
  294.  
  295.     if(StatusWindow)
  296.         ClearMenuStrip(StatusWindow);
  297.  
  298.     if(FastWindow)
  299.         ClearMenuStrip(FastWindow);
  300.  
  301.     ReleaseSemaphore(&MenuSemaphore);
  302. }
  303.  
  304.     /* AttachMenu():
  305.      *
  306.      *    Rebuild the main menu (if necessary) and attach it to the other windows.
  307.      */
  308.  
  309. BOOL
  310. AttachMenu(struct Menu *ThisMenu)
  311. {
  312.     BOOL Result;
  313.  
  314.     ObtainSemaphore(&MenuSemaphore);
  315.  
  316.     if(!ThisMenu)
  317.         ThisMenu = BuildMenu();
  318.  
  319.     if(ThisMenu)
  320.     {
  321.         if(Menu)
  322.         {
  323.             CopyMenuFlags(Menu,ThisMenu);
  324.  
  325.             ClearMenuStrips();
  326.  
  327.             LT_DisposeMenu(Menu);
  328.         }
  329.  
  330.         Menu = ThisMenu;
  331.  
  332.         SetMenuStrips(Menu);
  333.  
  334.         Result = TRUE;
  335.     }
  336.     else
  337.         Result = FALSE;
  338.  
  339.     ReleaseSemaphore(&MenuSemaphore);
  340.  
  341.     return(Result);
  342. }
  343.  
  344.     /* DisconnectDialMenu():
  345.      *
  346.      *    Disconnect the quick dial menu as its contents will
  347.      *    be invalid. This may happen if `term' fails to rebuild
  348.      *    the main menu due to memory shortage. Please note that
  349.      *    disconnecting the menu this way is legal only for menus
  350.      *    created by gtlayout.library.
  351.      */
  352.  
  353. VOID
  354. DisconnectDialMenu()
  355. {
  356.     ObtainSemaphore(&MenuSemaphore);
  357.  
  358.     if(Menu)
  359.     {
  360.         struct Menu *ThisMenu,*LastMenu = NULL;
  361.  
  362.         ClearMenuStrips();
  363.  
  364.         for(ThisMenu = Menu ; ThisMenu ; LastMenu = ThisMenu, ThisMenu = ThisMenu->NextMenu)
  365.         {
  366.             if(!ThisMenu->NextMenu && (ULONG)GTMENU_USERDATA(ThisMenu) == DIAL_MENU_LIMIT)
  367.             {
  368.                 LastMenu->NextMenu = NULL;
  369.                 break;
  370.             }
  371.         }
  372.  
  373.         SetMenuStrips(Menu);
  374.     }
  375.  
  376.     ReleaseSemaphore(&MenuSemaphore);
  377. }
  378.  
  379.     /* BuildMenu():
  380.      *
  381.      *    Create the menu strip, including the quick dial menu.
  382.      */
  383.  
  384. struct Menu *
  385. BuildMenu()
  386. {
  387.     LONG PhoneCount,Grouped,NotGrouped,Groups,Separator,i,j;
  388.     PhoneEntry **Phonebook = GlobalPhoneHandle->Phonebook;
  389.     BOOL SpeechAvailable;
  390.  
  391.         /* Check if the speech synthesizer is available. */
  392.  
  393.     SpeechAvailable = SpeechSynthesizerAvailable();
  394.  
  395.         /* Reset the variables. */
  396.  
  397.     Grouped = NotGrouped = Groups = PhoneCount = Separator = 0;
  398.  
  399.         /* Add the quick dial entries. This is not your basic */
  400.         /* O(N) algorithm :-/ */
  401.  
  402.     if(GlobalPhoneHandle->Phonebook && GlobalPhoneHandle->NumPhoneEntries > 0)
  403.     {
  404.         for(i = 0 ; PhoneCount < DIAL_MENU_MAX && i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  405.         {
  406.             if(Phonebook[i]->Header->QuickMenu)
  407.             {
  408.                 PhoneCount++;
  409.  
  410.                     /* Check if this entry is in a group */
  411.  
  412.                 if(Phonebook[i]->ThisGroup)
  413.                 {
  414.                     BOOL FirstOne = TRUE;
  415.  
  416.                     Grouped++;
  417.  
  418.                         /* Are there other entries in this group? */
  419.  
  420.                     for(j = 0 ; j < i ; j++)
  421.                     {
  422.                         if(Phonebook[j]->Header->QuickMenu && Phonebook[j]->ThisGroup == Phonebook[i]->ThisGroup)
  423.                         {
  424.                             FirstOne = FALSE;
  425.  
  426.                             break;
  427.                         }
  428.                     }
  429.  
  430.                         /* Is this the first one? */
  431.  
  432.                     if(FirstOne)
  433.                         Groups++;
  434.                 }
  435.                 else
  436.                     NotGrouped++;
  437.             }
  438.         }
  439.  
  440.             /* Will we need to mix grouped and ungrouped entries? */
  441.  
  442.         if(Grouped && NotGrouped)
  443.             Separator = 1;
  444.         else
  445.             Separator = 0;
  446.     }
  447.  
  448.         /* Don't do the work if no quick dial menu needs to be built */
  449.  
  450.     if(PhoneCount)
  451.     {
  452.         struct NewMenu *NewMenu;
  453.  
  454.             /* Allocate new menu prototypes */
  455.  
  456.         if(NewMenu = (struct NewMenu *)AllocVecPooled((NumMenuEntries + PhoneCount + Groups + Separator) * sizeof(struct NewMenu),MEMF_ANY | MEMF_CLEAR))
  457.         {
  458.             struct Menu    *ThisMenu;
  459.             LONG         Count;
  460.  
  461.                 /* Reset the menu type */
  462.  
  463.             TermMenu[NumMenuEntries - 2].nm_Type        = NM_TITLE;
  464.             TermMenu[NumMenuEntries - 2].nm_UserData    = (APTR)DIAL_MENU_LIMIT;
  465.  
  466.             CopyMem(TermMenu,NewMenu,NumMenuEntries * sizeof(struct NewMenu));
  467.  
  468.             FirstDialMenu = -1;
  469.  
  470.             Count = NumMenuEntries - 1;
  471.  
  472.                 /* Are we to pull entries just from one single group? */
  473.  
  474.             if(Grouped == 1 && !NotGrouped)
  475.             {
  476.                 for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  477.                 {
  478.                     if(Phonebook[i]->Header->QuickMenu)
  479.                     {
  480.                         NewMenu[Count].nm_Type        = NM_ITEM;
  481.                         NewMenu[Count].nm_Label        = Phonebook[i]->Header->Name;
  482.                         NewMenu[Count].nm_Flags        = CHECKIT|MENUTOGGLE;
  483.                         NewMenu[Count].nm_UserData    = (APTR)(DIAL_MENU_LIMIT + i);
  484.                         NewMenu[Count].nm_CommKey    = NULL;
  485.  
  486.                         Count++;
  487.  
  488.                         if(FirstDialMenu == -1)
  489.                             FirstDialMenu = DIAL_MENU_LIMIT + i;
  490.                     }
  491.                 }
  492.             }
  493.             else
  494.             {
  495.                     /* First step: collect the entries that don't belong into groups */
  496.  
  497.                 for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  498.                 {
  499.                     if(Phonebook[i]->Header->QuickMenu && !Phonebook[i]->ThisGroup)
  500.                     {
  501.                         NewMenu[Count].nm_Type        = NM_ITEM;
  502.                         NewMenu[Count].nm_Label        = Phonebook[i]->Header->Name;
  503.                         NewMenu[Count].nm_Flags        = CHECKIT|MENUTOGGLE;
  504.                         NewMenu[Count].nm_UserData    = (APTR)(DIAL_MENU_LIMIT + i);
  505.                         NewMenu[Count].nm_CommKey    = NULL;
  506.  
  507.                         Count++;
  508.  
  509.                         if(FirstDialMenu == -1)
  510.                             FirstDialMenu = DIAL_MENU_LIMIT + i;
  511.                     }
  512.                 }
  513.  
  514.                     /* If there needs to be a separator, add it */
  515.  
  516.                 if(Separator)
  517.                 {
  518.                     NewMenu[Count].nm_Type        = NM_ITEM;
  519.                     NewMenu[Count].nm_Label        = NM_BARLABEL;
  520.                     NewMenu[Count].nm_Flags        = NULL;
  521.                     NewMenu[Count].nm_UserData    = NULL;
  522.                     NewMenu[Count].nm_CommKey    = NULL;
  523.  
  524.                     Count++;
  525.                 }
  526.  
  527.                     /* Second step: collect the remaining entries that belong into groups */
  528.  
  529.                 for(i = 0 ; i < GlobalPhoneHandle->NumPhoneEntries ; i++)
  530.                 {
  531.                     if(Phonebook[i]->Header->QuickMenu && Phonebook[i]->ThisGroup)
  532.                     {
  533.                         BOOL FirstOne = TRUE;
  534.  
  535.                         for(j = 0 ; j < i ; j++)
  536.                         {
  537.                             if(Phonebook[j]->Header->QuickMenu && Phonebook[j]->ThisGroup && Phonebook[j]->ThisGroup == Phonebook[i]->ThisGroup)
  538.                             {
  539.                                 FirstOne = FALSE;
  540.                                 break;
  541.                             }
  542.                         }
  543.  
  544.                         if(FirstOne)
  545.                         {
  546.                             LONG k;
  547.  
  548.                             NewMenu[Count].nm_Type        = NM_ITEM;
  549.                             NewMenu[Count].nm_Label        = Phonebook[i]->ThisGroup->LocalName;
  550.                             NewMenu[Count].nm_Flags        = NULL;
  551.                             NewMenu[Count].nm_UserData    = NULL;
  552.                             NewMenu[Count].nm_CommKey    = NULL;
  553.  
  554.                             Count++;
  555.  
  556.                             for(k = i ; k < GlobalPhoneHandle->NumPhoneEntries ; k++)
  557.                             {
  558.                                 if(Phonebook[k]->Header->QuickMenu && Phonebook[k]->ThisGroup == Phonebook[i]->ThisGroup)
  559.                                 {
  560.                                     NewMenu[Count].nm_Type    = NM_SUB;
  561.                                     NewMenu[Count].nm_Label    = Phonebook[k]->Header->Name;
  562.                                     NewMenu[Count].nm_Flags    = CHECKIT|MENUTOGGLE;
  563.                                     NewMenu[Count].nm_UserData    = (APTR)(DIAL_MENU_LIMIT + k);
  564.                                     NewMenu[Count].nm_CommKey    = NULL;
  565.  
  566.                                     Count++;
  567.  
  568.                                     if(FirstDialMenu == -1)
  569.                                         FirstDialMenu = DIAL_MENU_LIMIT + k;
  570.                                 }
  571.                             }
  572.                         }
  573.                     }
  574.                 }
  575.  
  576.             }
  577.  
  578.             NewMenu[Count].nm_Type = NM_END;
  579.  
  580.                 /* If the speech synthesizer is not available, disconnect */
  581.                 /* the speech settings menu item */
  582.  
  583.             for(i = Count - 1 ; i >= 0 ; i--)
  584.             {
  585.                 if(TermMenu[i].nm_UserData == (APTR)MEN_SPEECH)
  586.                 {
  587.                     if(SpeechAvailable)
  588.                         TermMenu[i].nm_Flags &= ~NM_ITEMDISABLED;
  589.                     else
  590.                         TermMenu[i].nm_Flags |= NM_ITEMDISABLED;
  591.                 }
  592.  
  593.                 if(TermMenu[i].nm_UserData == (APTR)MEN_EXECUTE_REXX_COMMAND)
  594.                 {
  595.                     if(!RexxSysBase)
  596.                         TermMenu[i].nm_Type |= NM_ITEMDISABLED;
  597.                 }
  598.             }
  599.  
  600.                 /* Now layout the menu */
  601.  
  602.             ThisMenu = LT_NewMenuTemplate(Window->WScreen,NULL,AmigaGlyph,CheckGlyph,NULL,NewMenu);
  603.  
  604.                 /* We don't need this any more */
  605.  
  606.             FreeVecPooled(NewMenu);
  607.  
  608.                 /* Successful? */
  609.  
  610.             if(ThisMenu)
  611.                 return(ThisMenu);
  612.         }
  613.     }
  614.  
  615.         /* If the speech synthesizer is not available, disconnect */
  616.         /* the speech settings menu item */
  617.  
  618.     for(i = NumMenuEntries - 1 ; i >= 0 ; i--)
  619.     {
  620.         if(TermMenu[i].nm_UserData == (APTR)MEN_SPEECH)
  621.         {
  622.             if(SpeechAvailable)
  623.                 TermMenu[i].nm_Flags &= ~NM_ITEMDISABLED;
  624.             else
  625.                 TermMenu[i].nm_Flags |= NM_ITEMDISABLED;
  626.         }
  627.  
  628.         if(TermMenu[i].nm_UserData == (APTR)MEN_EXECUTE_REXX_COMMAND)
  629.         {
  630.             if(!RexxSysBase)
  631.                 TermMenu[i].nm_Flags |= NM_ITEMDISABLED;
  632.             else
  633.                 TermMenu[i].nm_Flags &= ~NM_ITEMDISABLED;
  634.         }
  635.     }
  636.  
  637.         /* Disconnect the quick dial menu */
  638.  
  639.     TermMenu[NumMenuEntries - 2].nm_Type = NM_END;
  640.  
  641.         /* Create the default menu strip */
  642.  
  643.     return(LT_NewMenuTemplate(Window->WScreen,NULL,AmigaGlyph,CheckGlyph,NULL,TermMenu));
  644. }
  645.  
  646.     /* SetClipMenu(BYTE Mode):
  647.      *
  648.      *    Enable/disable the copy/clear selection menu items.
  649.      */
  650.  
  651. VOID
  652. SetClipMenu(BOOL Mode)
  653. {
  654.     if(Mode && RasterEnabled)
  655.     {
  656.         OnItem(MEN_COPY);
  657.         OnItem(MEN_CLEAR);
  658.     }
  659.     else
  660.     {
  661.         OffItem(MEN_COPY);
  662.         OffItem(MEN_CLEAR);
  663.     }
  664. }
  665.  
  666.     /* SetRedialMenu():
  667.      *
  668.      *    Make the `redial' menu item available or make it
  669.      *    unavailable.
  670.      */
  671.  
  672. VOID
  673. SetRedialMenu()
  674. {
  675.     BOOL NoDialList;
  676.  
  677.     if(GlobalPhoneHandle->DialList)
  678.         NoDialList = IsListEmpty(GlobalPhoneHandle->DialList);
  679.     else
  680.         NoDialList = TRUE;
  681.  
  682.     if(!NoDialList && (DialItemsAvailable || Config->MiscConfig->ProtectiveMode))
  683.         OnItem(MEN_REDIAL);
  684.     else
  685.         OffItem(MEN_REDIAL);
  686. }
  687.  
  688.     /* SetDialMenu(BOOL Mode):
  689.      *
  690.      *    Block or enable the dialing menu.
  691.      */
  692.  
  693. VOID
  694. SetDialMenu(BOOL Mode)
  695. {
  696.     if(Window && Menu)
  697.     {
  698.         if(Mode || Config->MiscConfig->ProtectiveMode)
  699.         {
  700.             BOOL NoDialList;
  701.  
  702.             if(GlobalPhoneHandle->DialList)
  703.                 NoDialList = IsListEmpty(GlobalPhoneHandle->DialList);
  704.             else
  705.                 NoDialList = TRUE;
  706.  
  707.             if(NoDialList)
  708.                 OffItem(MEN_REDIAL);
  709.             else
  710.                 OnItem(MEN_REDIAL);
  711.  
  712.             OnItem(MEN_DIAL_NUMBER);
  713.  
  714.             if(FirstDialMenu != -1)
  715.                 OnItem(MEN_EXTRA_DIAL);
  716.         }
  717.         else
  718.         {
  719.             OffItem(MEN_REDIAL);
  720.             OffItem(MEN_DIAL_NUMBER);
  721.  
  722.             if(FirstDialMenu != -1)
  723.                 OffItem(MEN_EXTRA_DIAL);
  724.         }
  725.  
  726.         DialItemsAvailable = Mode;
  727.     }
  728. }
  729.  
  730.     /* SetTransferMenu(BOOL Mode):
  731.      *
  732.      *    Block or enable the transfer menu.
  733.      */
  734.  
  735. VOID
  736. SetTransferMenu(BOOL Mode)
  737. {
  738.     if(Window && Menu)
  739.     {
  740.         BOOL    ValidDefault,
  741.                 ValidASCIIDownload,
  742.                 ValidASCIIUpload,
  743.                 ValidTextDownload,
  744.                 ValidTextUpload,
  745.                 ValidBinaryDownload,
  746.                 ValidBinaryUpload;
  747.  
  748.         if(!Config->TransferConfig->DefaultLibrary[0] || !Mode || (!XProtocolBase && Config->TransferConfig->DefaultType == XFER_XPR))
  749.             ValidDefault = FALSE;
  750.         else
  751.             ValidDefault = TRUE;
  752.  
  753.         switch(Config->TransferConfig->ASCIIUploadType)
  754.         {
  755.             case XFER_INTERNAL:
  756.  
  757.                 ValidASCIIUpload = TRUE;
  758.                 break;
  759.  
  760.             case XFER_DEFAULT:
  761.  
  762.                 ValidASCIIUpload = ValidDefault;
  763.                 break;
  764.  
  765.             case XFER_XPR:
  766.             case XFER_EXTERNALPROGRAM:
  767.  
  768.                 ValidASCIIUpload = Config->TransferConfig->ASCIIUploadLibrary[0];
  769.                 break;
  770.         }
  771.  
  772.         switch(Config->TransferConfig->ASCIIDownloadType)
  773.         {
  774.             case XFER_INTERNAL:
  775.  
  776.                 ValidASCIIDownload = TRUE;
  777.                 break;
  778.  
  779.             case XFER_DEFAULT:
  780.  
  781.                 ValidASCIIDownload = ValidDefault;
  782.                 break;
  783.  
  784.             case XFER_XPR:
  785.             case XFER_EXTERNALPROGRAM:
  786.  
  787.                 ValidASCIIDownload = Config->TransferConfig->ASCIIDownloadLibrary[0];
  788.                 break;
  789.         }
  790.  
  791.  
  792.         switch(Config->TransferConfig->TextUploadType)
  793.         {
  794.             case XFER_DEFAULT:
  795.  
  796.                 ValidTextUpload = ValidDefault;
  797.                 break;
  798.  
  799.             case XFER_XPR:
  800.             case XFER_EXTERNALPROGRAM:
  801.  
  802.                 ValidTextUpload = Config->TransferConfig->TextUploadLibrary[0];
  803.                 break;
  804.         }
  805.  
  806.         switch(Config->TransferConfig->TextDownloadType)
  807.         {
  808.             case XFER_DEFAULT:
  809.  
  810.                 ValidTextDownload = ValidDefault;
  811.                 break;
  812.  
  813.             case XFER_XPR:
  814.             case XFER_EXTERNALPROGRAM:
  815.  
  816.                 ValidTextDownload = Config->TransferConfig->TextDownloadLibrary[0];
  817.                 break;
  818.         }
  819.  
  820.         switch(Config->TransferConfig->BinaryUploadType)
  821.         {
  822.             case XFER_DEFAULT:
  823.  
  824.                 ValidBinaryUpload = ValidDefault;
  825.                 break;
  826.  
  827.             case XFER_XPR:
  828.             case XFER_EXTERNALPROGRAM:
  829.  
  830.                 ValidBinaryUpload = Config->TransferConfig->BinaryUploadLibrary[0];
  831.                 break;
  832.         }
  833.  
  834.         switch(Config->TransferConfig->BinaryDownloadType)
  835.         {
  836.             case XFER_DEFAULT:
  837.  
  838.                 ValidBinaryDownload = ValidDefault;
  839.                 break;
  840.  
  841.             case XFER_XPR:
  842.             case XFER_EXTERNALPROGRAM:
  843.  
  844.                 ValidBinaryDownload = Config->TransferConfig->BinaryDownloadLibrary[0];
  845.                 break;
  846.         }
  847.  
  848. #ifdef BUILTIN_ZMODEM
  849.         if(UseInternalZModem)
  850.             ValidDefault = ValidBinaryDownload = ValidBinaryUpload = ValidTextDownload = TRUE;
  851. #endif    /* BUILTIN_ZMODEM */
  852.  
  853.         if(ValidASCIIUpload)
  854.             OnItem(MEN_UPLOAD_ASCII);
  855.         else
  856.             OffItem(MEN_UPLOAD_ASCII);
  857.  
  858.         if(ValidASCIIDownload)
  859.             OnItem(MEN_DOWNLOAD_ASCII);
  860.         else
  861.             OffItem(MEN_DOWNLOAD_ASCII);
  862.  
  863.         if(ValidTextUpload)
  864.         {
  865.             OnItem(MEN_UPLOAD_TEXT);
  866.             OnItem(MEN_EDIT_AND_UPLOAD_TEXT);
  867.         }
  868.         else
  869.         {
  870.             OffItem(MEN_UPLOAD_TEXT);
  871.             OffItem(MEN_EDIT_AND_UPLOAD_TEXT);
  872.         }
  873.  
  874. #ifdef BUILTIN_ZMODEM
  875.         if(UseInternalZModem)
  876.             OnItem(MEN_UPLOAD_TEXT);
  877. #endif    /* BUILTIN_ZMODEM */
  878.  
  879.         if(ValidTextDownload)
  880.             OnItem(MEN_DOWNLOAD_TEXT);
  881.         else
  882.             OffItem(MEN_DOWNLOAD_TEXT);
  883.  
  884.         if(ValidBinaryUpload)
  885.             OnItem(MEN_UPLOAD_BINARY);
  886.         else
  887.             OffItem(MEN_UPLOAD_BINARY);
  888.  
  889.         if(ValidBinaryDownload)
  890.             OnItem(MEN_DOWNLOAD_BINARY);
  891.         else
  892.             OffItem(MEN_DOWNLOAD_BINARY);
  893.  
  894.         if(ValidDefault)
  895.             OnItem(MEN_TRANSFER);
  896.         else
  897.             OffItem(MEN_TRANSFER);
  898.     }
  899. }
  900.  
  901.     /* SetRasterMenu(BOOL Mode):
  902.      *
  903.      *    Block or enable the menu entries associated with
  904.      *    functions to access the screen raster.
  905.      */
  906.  
  907. VOID
  908. SetRasterMenu(BOOL Mode)
  909. {
  910.     if(Window && Menu)
  911.     {
  912.         if(Mode)
  913.         {
  914.             OnItem(MEN_SAVE_AS_TEXT);
  915.             OnItem(MEN_PRINT_SCREEN);
  916.         }
  917.         else
  918.         {
  919.             OffItem(MEN_SAVE_AS_TEXT);
  920.             OffItem(MEN_PRINT_SCREEN);
  921.         }
  922.     }
  923. }
  924.  
  925.     /* LookForIt(struct MenuItem *Item,ULONG ID):
  926.      *
  927.      *    Auxilary routine for FindThisItem(), scans
  928.      *    menu item and sub item lists.
  929.      */
  930.  
  931. STATIC struct MenuItem *
  932. LookForIt(struct MenuItem *Item,ULONG ID)
  933. {
  934.     while(Item)
  935.     {
  936.         if((ULONG)GTMENUITEM_USERDATA(Item) == ID)
  937.             return(Item);
  938.         else
  939.         {
  940.             if(Item->SubItem)
  941.             {
  942.                 struct MenuItem *TheItem;
  943.  
  944.                 if(TheItem = LookForIt(Item->SubItem,ID))
  945.                     return(TheItem);
  946.             }
  947.  
  948.             Item = Item->NextItem;
  949.         }
  950.     }
  951.  
  952.     return(NULL);
  953. }
  954.  
  955.     /* FindThisItem(struct Menu *FirstMenu,ULONG MenuID):
  956.      *
  957.      *    Scan a menu for a menuitem associated with a
  958.      *    menu ID.
  959.      */
  960.  
  961. STATIC struct MenuItem *
  962. FindThisItem(struct Menu *FirstMenu,ULONG MenuID)
  963. {
  964.     struct MenuItem *FoundItem = NULL;
  965.  
  966.     SafeObtainSemaphoreShared(&MenuSemaphore);
  967.  
  968.     if(TypeOfMem(FirstMenu))
  969.     {
  970.         struct MenuItem *Item;
  971.  
  972.         while(FirstMenu)
  973.         {
  974.             if(Item = LookForIt(FirstMenu->FirstItem,MenuID))
  975.             {
  976.                 FoundItem = Item;
  977.                 break;
  978.             }
  979.             else
  980.                 FirstMenu = FirstMenu->NextMenu;
  981.         }
  982.     }
  983.  
  984.     ReleaseSemaphore(&MenuSemaphore);
  985.  
  986.     return(FoundItem);
  987. }
  988.  
  989. STATIC struct Menu *
  990. FindThisMenu(struct Menu *FirstMenu,ULONG MenuID)
  991. {
  992.     struct Menu *FoundMenu = NULL;
  993.  
  994.     SafeObtainSemaphoreShared(&MenuSemaphore);
  995.  
  996.     if(TypeOfMem(FirstMenu))
  997.     {
  998.         while(FirstMenu)
  999.         {
  1000.             if(GTMENU_USERDATA(FirstMenu) == (APTR)MenuID)
  1001.             {
  1002.                 FoundMenu = FirstMenu;
  1003.                 break;
  1004.             }
  1005.             else
  1006.                 FirstMenu = FirstMenu->NextMenu;
  1007.         }
  1008.     }
  1009.  
  1010.     ReleaseSemaphore(&MenuSemaphore);
  1011.  
  1012.     return(FoundMenu);
  1013. }
  1014.  
  1015.     /* GetItem(ULONG MenuID):
  1016.      *
  1017.      *    Get the checkmark state of a menu item.
  1018.      */
  1019.  
  1020. BOOL
  1021. GetItem(ULONG MenuID)
  1022. {
  1023.     BOOL Result = FALSE;
  1024.  
  1025.     SafeObtainSemaphoreShared(&MenuSemaphore);
  1026.  
  1027.     if(Menu)
  1028.     {
  1029.         struct MenuItem *Item;
  1030.  
  1031.         if(Item = FindThisItem(Menu,MenuID))
  1032.         {
  1033.             if(Item->Flags & CHECKED)
  1034.                 Result = TRUE;
  1035.         }
  1036.     }
  1037.  
  1038.     ReleaseSemaphore(&MenuSemaphore);
  1039.  
  1040.     return(Result);
  1041. }
  1042.  
  1043.     /* SetItem(ULONG MenuID,BOOL Mode):
  1044.      *
  1045.      *    Clear or set the checkmark or state of a menu item.
  1046.      */
  1047.  
  1048. VOID
  1049. SetItem(ULONG MenuID,BOOL Mode)
  1050. {
  1051.     ObtainSemaphore(&MenuSemaphore);
  1052.  
  1053.         /* Is the global pull-down menu available? */
  1054.  
  1055.     if(Menu)
  1056.     {
  1057.         struct MenuItem    *Item;
  1058.         struct Menu    *ThisMenu;
  1059.  
  1060.         if(ThisMenu = FindThisMenu(Menu,MenuID))
  1061.         {
  1062.                 /* Remove the menu from the windows. */
  1063.  
  1064.             ClearMenuStrips();
  1065.  
  1066.             switch(Mode)
  1067.             {
  1068.                 case SETITEM_ON:
  1069.  
  1070.                     ThisMenu->Flags |= MENUENABLED;
  1071.                     break;
  1072.  
  1073.                 case SETITEM_OFF:
  1074.  
  1075.                     ThisMenu->Flags &= ~MENUENABLED;
  1076.                     break;
  1077.             }
  1078.  
  1079.                 /* Reattach the menu to the windows. */
  1080.  
  1081.             ResetMenuStrips(Menu);
  1082.         }
  1083.         else
  1084.         {
  1085.                 /* Try to find the menu item and change
  1086.                  * the state of the checkmark.
  1087.                  */
  1088.  
  1089.             if(Item = FindThisItem(Menu,MenuID))
  1090.             {
  1091.                     /* Remove the menu from the windows. */
  1092.  
  1093.                 ClearMenuStrips();
  1094.  
  1095.                 switch(Mode)
  1096.                 {
  1097.                     case SETITEM_SETCHECK:
  1098.  
  1099.                         Item->Flags |= CHECKED;
  1100.                         break;
  1101.  
  1102.                     case SETITEM_CLRCHECK:
  1103.  
  1104.                         Item->Flags &= ~CHECKED;
  1105.                         break;
  1106.  
  1107.                     case SETITEM_ON:
  1108.  
  1109.                         Item->Flags |= ITEMENABLED;
  1110.                         break;
  1111.  
  1112.                     case SETITEM_OFF:
  1113.  
  1114.                         Item->Flags &= ~ITEMENABLED;
  1115.                         break;
  1116.                 }
  1117.  
  1118.                     /* Reattach the menu to the windows. */
  1119.  
  1120.                 ResetMenuStrips(Menu);
  1121.             }
  1122.         }
  1123.     }
  1124.  
  1125.     ReleaseSemaphore(&MenuSemaphore);
  1126. }
  1127.  
  1128.     /* CreateMenuGlyphs():
  1129.      *
  1130.      *    Create scaled glyphs for pull-down menus.
  1131.      */
  1132.  
  1133. BOOL
  1134. CreateMenuGlyphs(struct Screen *Screen,struct DrawInfo *DrawInfo,struct Image **AmigaPtr,struct Image **CheckPtr)
  1135. {
  1136.     struct Image *AmigaGlyph,*CheckGlyph;
  1137.     LONG AspectX,AspectY,Size,FontHeight;
  1138.  
  1139.     FontHeight = DrawInfo->dri_Font->tf_Baseline + 2;
  1140.  
  1141.     if(Screen->Flags & SCREENHIRES)
  1142.         Size = SYSISIZE_MEDRES;
  1143.     else
  1144.         Size = SYSISIZE_LOWRES;
  1145.  
  1146.     AspectX = DrawInfo->dri_Resolution.X;
  1147.     AspectY = DrawInfo->dri_Resolution.Y;
  1148.  
  1149.     AmigaGlyph = NewObject(NULL,SYSICLASS,
  1150.         SYSIA_DrawInfo,    DrawInfo,
  1151.         SYSIA_Size,        Size,
  1152.         SYSIA_Which,    AMIGAKEY,
  1153.         IA_Left,        0,
  1154.         LA_Top,            0,
  1155.         IA_Width,        (FontHeight * 3 * AspectY) / (2 * AspectX),
  1156.         IA_Height,        FontHeight,
  1157.     TAG_DONE);
  1158.  
  1159.     CheckGlyph = NewObject(NULL,SYSICLASS,
  1160.         SYSIA_DrawInfo,    DrawInfo,
  1161.         SYSIA_Size,        Size,
  1162.         SYSIA_Which,    MENUCHECK,
  1163.         IA_Left,        0,
  1164.         LA_Top,            0,
  1165.         IA_Width,        (FontHeight * AspectY) / AspectX,
  1166.         IA_Height,        FontHeight,
  1167.     TAG_DONE);
  1168.  
  1169.     if(AmigaGlyph && CheckGlyph)
  1170.     {
  1171.         *AmigaPtr = AmigaGlyph;
  1172.         *CheckPtr = CheckGlyph;
  1173.  
  1174.         return(TRUE);
  1175.     }
  1176.     else
  1177.     {
  1178.         DisposeObject(AmigaGlyph);
  1179.         DisposeObject(CheckGlyph);
  1180.  
  1181.         return(FALSE);
  1182.     }
  1183. }
  1184.